package com.wwcom.darteagle.model;

import java.util.ArrayList;
import java.util.List;

public class MatchSets extends Match {
	private List<Set> sets;
	
	private Set currentSet;
	private MatchPlayer setWinner;
	private boolean isSetComplete;
	private boolean isMatchComplete;
	
	
	public MatchSets() {
		super();
	}
	
	public MatchSets(MatchInfo matchInfo) {
		super(matchInfo);
	}

	@Override
	protected void initialiseSelf() {
		super.initialiseSelf();
		sets= null;
		currentSet= null;
		setWinner= null;
		isSetComplete= false;
		isMatchComplete= false;
	}
	
	
	//accessors
	@Override
	public int getNumSets() {
		return matchInfo.getNumSets();
	}
	
	@Override
	public void setNumSets(int numSets) {
		matchInfo.setNumSets(numSets);
	}	
	
	@Override
	public MatchPlayer getLegWinner() {
		return currentSet.getLegWinner();
	}
	
	@Override
	public MatchPlayer getSetWinner() {
		return setWinner;		
	}
	
	@Override
	public boolean isLegComplete() {
		return currentSet.isLegComplete();
	}

	@Override
	public boolean isSetComplete() {
		return isSetComplete;
	}

	@Override
	public boolean isMatchComplete() {
		return isMatchComplete;
	}

	@Override
	public int getLegNumber() {
		return currentSet.getLegNumber();
	}
	
	@Override
	public int getSetNumber() {
		return sets.size()-1;
	}	
	
	@Override
	public List<Set> getSets() {
		return sets;		
	}
	

	//display and messages
	@Override
	public List< List<VisitScore> > getLegHistory() {
		return currentSet.getLegHistory();
	}
	
	protected void updateLegHistory() {
	   currentSet.updateLegHistory();
	}
	
	@Override
	public List<VisitScore> getPlayerCurrentScores() {
		return currentSet.getPlayerCurrentScores();
	}
	
	protected void updatePlayerCurrentScores() {
		currentSet.updatePlayerCurrentScores();
	}
	//playing logic
	@Override
	public void startPlaying() {
		super.startPlaying(); //super class handles player logic
		if (sets != null)
			throw new RuntimeException("MatchSets::startPlaying - sets not null");
		//create sets list
		sets= new ArrayList<Set>();
		//add new set
		addSet();
		currentSet.startPlaying(setStartPlayer);		
	}
	
	@Override
	public void nextPlayer() {
		//add player statistics first before we finalise which puts an empty score on the list
		addPlayerStatistics(currentPlayer, getCurrentPlayerScore());
		
		currentSet.nextPlayer();
		
		//check for set winner
		if (currentSet.isSetComplete()) {
			isSetComplete= true;
			setWinner= currentSet.getSetWinner();

			//update matchPlayers
			setWinner.incNumSets();			
			for (MatchPlayer mp : matchPlayers) {
				mp.setNumLegs(0);
			}				
			
			if (setWinner.getNumSets() >= matchInfo.getNumSets()) {
				isMatchComplete= true;
			}
			
		}
		super.nextPlayer();		
	}

	@Override
	public void nextLeg() {
		super.nextLeg(); //keep this matches players in sync with the submatch
		currentSet.nextLeg();
	}	
	
	@Override
	public void nextSet() {
		addSet();
		isSetComplete= false;
		setWinner= null;
		super.nextSet(); //handles player rotation
		currentSet.startPlaying(setStartPlayer);
	}
	
	private void addSet() {
		Set set= new Set(matchInfo,matchPlayers);
		set.setSetInd(sets.size());
		sets.add(set);
		//set current Set
		currentSet= sets.get(sets.size()-1);
	}
	
	//scoring
	@Override
	public VisitScore updateCurrentPlayerScore( Score score ) {
		return currentSet.updateCurrentPlayerScore(score);
	}	
	
	@Override
	public VisitScore updatePlayerScore(MatchPlayer matchPlayer, int visitInd, Score score ) {
		return currentSet.updatePlayerScore(matchPlayer, visitInd, score);
	}
	
	@Override
	public void finalisePlayerScore(MatchPlayer matchPlayer, int visitInd) {
		currentSet.finalisePlayerScore(matchPlayer, visitInd);
		//check for set winner
		if (currentSet.isSetComplete()) {
			isSetComplete= true;
			setWinner= currentSet.getSetWinner();

			//update matchPlayers
			setWinner.incNumSets();			
			for (MatchPlayer mp : matchPlayers) {
				mp.setNumLegs(0);
			}				
			
			if (setWinner.getNumSets() >= matchInfo.getNumSets()) {
				isMatchComplete= true;
			}			
		}
		//update statistics
		updatePlayerStatistics(matchPlayer);
	}
	
	@Override
	public void unFinalisePlayerScore(MatchPlayer matchPlayer, int visitInd) {
		currentSet.unFinalisePlayerScore(matchPlayer, visitInd);	
	}	
	
	@Override
	public VisitScore getCurrentPlayerScore() {
		return currentSet.getCurrentPlayerScore();
	}	
	
	@Override
	public VisitScore getVisitScore(MatchPlayer matchPlayer, int visitInd) {
		return currentSet.getVisitScore(matchPlayer,visitInd);
	}	

	//statistics
	@Override	
	public List<DartStats> getPlayerStatsLeg(int setInd, int legInd) {
		return sets.get(setInd).getPlayerStatsLeg(-1,legInd);
	}
	
	@Override	
	public List<DartStats> getPlayerStatsSet(int setInd) {
		return sets.get(setInd).getPlayerStats();
	}
	
	@Override	
	protected void updatePlayerStatistics(MatchPlayer matchPlayer) {
		//update set and match statistics - leg takes care of itsself
		currentSet.updatePlayerStatistics(matchPlayer);
		super.updatePlayerStatistics(matchPlayer);
	}
	
	@Override	
	protected List<VisitScore> getPlayerMatchHistory(MatchPlayer matchPlayer) {
		List < VisitScore > pmh= new ArrayList<VisitScore>();		
		for (Set s : sets) {
			pmh.addAll(s.getPlayerMatchHistory(matchPlayer));
		}
		return pmh;
	}	
	
	//database serialisation
	public List<VisitScore> getAllVisitScoresInVisitOrder() {		
		List<VisitScore> vsList= new ArrayList<VisitScore>();
		for (Set s : sets) {
			vsList.addAll(s.getAllVisitScoresInVisitOrder());
		}
		return vsList;
	}
	
}
